home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / bash / bash_108 / bash-108.zoo / bash-1.08 / copy_cmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-22  |  6.9 KB  |  260 lines

  1. /* copy_command.c -- copy a COMMAND structure.  This is needed
  2.    primarily for making function definitions, but I'm not sure
  3.    that anyone else will need it.  */
  4.  
  5. /* Copyright (C) 1987,1991 Free Software Foundation, Inc.
  6.  
  7.    This file is part of GNU Bash, the Bourne Again SHell.
  8.  
  9.    Bash is free software; you can redistribute it and/or modify it
  10.    under the terms of the GNU General Public License as published by
  11.    the Free Software Foundation; either version 1, or (at your option)
  12.    any later version.
  13.  
  14.    Bash is distributed in the hope that it will be useful, but WITHOUT
  15.    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  16.    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
  17.    License for more details.
  18.  
  19.    You should have received a copy of the GNU General Public License
  20.    along with Bash; see the file COPYING.  If not, write to the Free
  21.    Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  22.  
  23. #include <stdio.h>
  24. #include "shell.h"
  25.  
  26. /* Forward declaration. */
  27. extern COMMAND *copy_command ();
  28.  
  29. WORD_DESC *
  30. copy_word (word)
  31.      WORD_DESC *word;
  32. {
  33.   WORD_DESC *new_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
  34.   bcopy (word, new_word, sizeof (WORD_DESC));
  35.   new_word->word = savestring (word->word);
  36.   return (new_word);
  37. }
  38.  
  39. /* Copy the chain of words in LIST.  Return a pointer to 
  40.    the new chain. */
  41. WORD_LIST *
  42. copy_word_list (list)
  43.      WORD_LIST *list;
  44. {
  45.   WORD_LIST *new_list = NULL;
  46.  
  47.   while (list) {
  48.     WORD_LIST *temp = (WORD_LIST *)xmalloc (sizeof (WORD_LIST));
  49.     temp->next = new_list;
  50.     new_list = temp;
  51.     new_list->word = copy_word (list->word);
  52.     list = list->next;
  53.   }
  54.   return ((WORD_LIST *)reverse_list (new_list));
  55. }
  56.  
  57. PATTERN_LIST *
  58. copy_case_clause (clause)
  59.      PATTERN_LIST *clause;
  60. {
  61.   PATTERN_LIST *new_clause = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST));
  62.   new_clause->patterns = copy_word_list (clause->patterns);
  63.   new_clause->action = copy_command (clause->action);
  64.   return (new_clause);
  65. }
  66.  
  67. PATTERN_LIST *
  68. copy_case_clauses (clauses)
  69.      PATTERN_LIST *clauses;
  70. {
  71.   PATTERN_LIST *new_list = (PATTERN_LIST *)NULL;
  72.  
  73.   while (clauses) {
  74.     PATTERN_LIST *new_clause = copy_case_clause (clauses);
  75.     new_clause->next = new_list;
  76.     new_list = new_clause;
  77.     clauses = clauses->next;
  78.   }
  79.   return ((PATTERN_LIST *)reverse_list (new_list));
  80. }
  81.  
  82. /* Copy a single redirect. */
  83. REDIRECT *
  84. copy_redirect (redirect)
  85.      REDIRECT *redirect;
  86. {
  87.   REDIRECT *new_redirect = (REDIRECT *)xmalloc (sizeof (REDIRECT));
  88.   bcopy (redirect, new_redirect, (sizeof (REDIRECT)));
  89.   switch (redirect->instruction)
  90.     {
  91.     case r_reading_until:
  92.     case r_deblank_reading_until:
  93.       new_redirect->here_doc_eof = savestring (redirect->here_doc_eof);
  94.       /* There is NO BREAK HERE ON PURPOSE!!!! */
  95.     case r_appending_to:
  96.     case r_output_direction:
  97.     case r_input_direction:
  98.     case r_inputa_direction:
  99.     case r_err_and_out:
  100.     case r_input_output:
  101.     case r_output_force:
  102.       new_redirect->redirectee.filename =
  103.     copy_word (redirect->redirectee.filename);
  104.       break;
  105.     }
  106.   return (new_redirect);
  107. }
  108.   
  109. REDIRECT *
  110. copy_redirects (list)
  111.      REDIRECT *list;
  112. {
  113.   REDIRECT *new_list = NULL;
  114.  
  115.   while (list) {
  116.     REDIRECT *temp = copy_redirect (list);
  117.     temp->next = new_list;
  118.     new_list = temp;
  119.     list = list->next;
  120.   }
  121.   return ((REDIRECT *)reverse_list (new_list));
  122. }
  123.   
  124. FOR_COM *
  125. copy_for_command (com)
  126.      FOR_COM *com;
  127. {
  128.   FOR_COM *new_for = (FOR_COM *)xmalloc (sizeof (FOR_COM));
  129.   new_for->name = copy_word (com->name);
  130.   new_for->map_list = copy_word_list (com->map_list);
  131.   new_for->action = copy_command (com->action);
  132.   return (new_for);
  133. }
  134.  
  135. GROUP_COM *
  136. copy_group_command (com)
  137.      GROUP_COM *com;
  138. {
  139.   GROUP_COM *new_group = (GROUP_COM *)xmalloc (sizeof (GROUP_COM));
  140.  
  141.   new_group->command = copy_command (com->command);
  142.   return (new_group);
  143. }
  144.  
  145. CASE_COM *
  146. copy_case_command (com)
  147.      CASE_COM *com;
  148. {
  149.   CASE_COM *new_case = (CASE_COM *)xmalloc (sizeof (CASE_COM));
  150.   new_case->word = copy_word (com->word);
  151.   new_case->clauses = copy_case_clauses (com->clauses);
  152.   return (new_case);
  153. }
  154.  
  155. WHILE_COM *
  156. copy_while_command (com)
  157.      WHILE_COM *com;
  158. {
  159.   WHILE_COM *new_while = (WHILE_COM *)xmalloc (sizeof (WHILE_COM));
  160.   new_while->test = copy_command (com->test);
  161.   new_while->action = copy_command (com->action);
  162.   return (new_while);
  163. }
  164.  
  165. IF_COM *
  166. copy_if_command (com)
  167.      IF_COM *com;
  168. {
  169.   IF_COM *new_if = (IF_COM *)xmalloc (sizeof (IF_COM));
  170.   new_if->test = copy_command (com->test);
  171.   new_if->true_case = copy_command (com->true_case);
  172.   new_if->false_case = copy_command (com->false_case);
  173.   return (new_if);
  174. }
  175.  
  176. SIMPLE_COM *
  177. copy_simple_command (com)
  178.      SIMPLE_COM *com;
  179. {
  180.   SIMPLE_COM *new_simple = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM));
  181.   new_simple->words = copy_word_list (com->words);
  182.   new_simple->redirects = copy_redirects (com->redirects);
  183.   return (new_simple);
  184. }
  185.   
  186. FUNCTION_DEF *
  187. copy_function_def (com)
  188.      FUNCTION_DEF *com;
  189. {
  190.   FUNCTION_DEF *new_def = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF));
  191.   new_def->name = copy_word (com->name);
  192.   new_def->command = copy_command (com->command);
  193.   return (new_def);
  194. }
  195.  
  196. /* Copy the command structure in COMMAND.  Return a pointer to the
  197.    copy.  Don't you forget to dispose_command () on this pointer
  198.    later! */
  199. COMMAND *
  200. copy_command (command)
  201.      COMMAND *command;
  202. {
  203.   if (!command) return ((COMMAND *)NULL);
  204.   {
  205.     COMMAND *new_command = (COMMAND *)xmalloc (sizeof (COMMAND));
  206.  
  207.     bcopy (command, new_command, sizeof (COMMAND));
  208.  
  209.     new_command->invert_pipeline = command->invert_pipeline; /* XXX */
  210.  
  211.     if (command->redirects)
  212.       new_command->redirects = copy_redirects (command->redirects);
  213.  
  214.     switch (command->type) {
  215.  
  216.     case cm_for:
  217.       new_command->value.For = copy_for_command (command->value.For);
  218.       break;
  219.  
  220.     case cm_group:
  221.       new_command->value.Group = copy_group_command (command->value.Group);
  222.       break;
  223.  
  224.     case cm_case:
  225.       new_command->value.Case = copy_case_command (command->value.Case);
  226.       break;
  227.       
  228.     case cm_until:
  229.     case cm_while:
  230.       new_command->value.While = copy_while_command (command->value.While);
  231.       break;
  232.       
  233.     case cm_if:
  234.       new_command->value.If = copy_if_command (command->value.If);
  235.       break;
  236.       
  237.     case cm_simple:
  238.       new_command->value.Simple = copy_simple_command (command->value.Simple);
  239.       break;
  240.       
  241.     case cm_connection:
  242.       {
  243.     CONNECTION *new_connection = (CONNECTION *)xmalloc (sizeof (CONNECTION));
  244.     new_connection->connector = command->value.Connection->connector;
  245.     new_connection->first = copy_command (command->value.Connection->first);
  246.     new_connection->second = copy_command (command->value.Connection->second);
  247.     new_command->value.Connection = new_connection;
  248.     break;
  249.       }
  250.       
  251.       /* Pathological case.  I'm not even sure that you can have a
  252.      function definition as part of a function definition. */
  253.     case cm_function_def:
  254.       new_command->value.Function_def = copy_function_def (command->value.Function_def);
  255.       break;
  256.     }
  257.   return (new_command);
  258.   }
  259. }
  260.